from network import *
from generate import GenerateNetwork
import multiprocessing
import time
import copy

# print(f"node数量： {node_num}")
# print("各项参数：")
# print(f"时隙数：{max_slot_num}，单轮实验次数：{the_num}，轮数：{loop_num}，weight倍乘系数：1，缩减系数：{Reduction_factor}")


start_time = time.time()

def worker(path_for_getxt, remaining_num_changing, node_num_changing):
    counter_bestresponse = 0
    counter_pro = 0
    counter_step = 0
    counter_remaining = 0

    waiting_bestresponse = 0
    waiting_pro = 0
    waiting_step = 0
    waiting_remaining = 0

    waste_bestresponse = 0
    waste_pro = 0
    waste_step = 0
    waste_remaining = 0

    for function in range(4):
        if function == 0:
            print()
            print("BestResponse算法：")
        elif function == 1:
            print()
            print("Pro_first算法:")
        elif function == 2:
            print()
            print("Step_first算法:")
        elif function == 3:
            print()
            print("Remainning_first算法:")

        ec_num_counter = 0
        waiting_time = 0
        el_waste = 0

        for_sd_num = 0

        for i in range(the_num):
            qnetwork = QNetwork(path_for_getxt, remaining_num_changing, node_num_changing)


            max_time_slot = max_slot_num
            num_timeslot = 0


            sd_pair_urgency = {}

            while max_time_slot:
                sdLList_before = []
                if qnetwork.sdList:
                    sdLList_before = copy.deepcopy(qnetwork.sdList) 
                    if function == 0:
                        Loop = qnetwork.BestResponse()
                        # print(f"本时隙经过{Loop}轮循环完成收敛")
                    elif function == 1:
                        qnetwork.Pro_first()
                    elif function == 2:
                        qnetwork.Step_first()
                    elif function == 3:
                        qnetwork.Remainning_first(sd_pair_urgency)
                
            #     # print(len(qnetwork.sdList))
                # print("el_success", qnetwork.el_success[4])
                # print("一次算法执行结束后的elMatrix")
                # print(qnetwork.elMatrix)
                    
                num_timeslot += 1
                max_time_slot -= 1

                new_ec_num = (len(sdLList_before)-len(qnetwork.sdList))
                waiting_time += new_ec_num*num_timeslot
                # print(f"waiting_time {waiting_time}, new_ec_num {new_ec_num}, num_timeslot {num_timeslot}" )
                ec_num_counter += (len(qnetwork.sdList_all)-len(qnetwork.sdList))


                for_sd_num = len(qnetwork.sdList_all)
                # print(ec_num_counter)

                # print(f"第{num_timeslot}个时隙")
                # print(f"共{len(qnetwork.sdList_all)}个ec")

                # print(f"已建成{len(qnetwork.sdList_all)-len(qnetwork.sdList)}个ec")

                # print(f"最新建成的ec有{set(tuple(x) for x in sdLList_before) - set(tuple(x) for x in qnetwork.sdList)}")

            #         print(qnetwork.sdList)
            # print("waiting time:", waiting_time)
            el_waste += qnetwork.elWaste
            # print("el_waste:", el_waste )
            if qnetwork.sdList:
                waiting_time += len(qnetwork.sdList)*max_slot_num
                # print(f"{len(qnetwork.sdList)} ec waiting to be built")
                # print("waiting time is :",waiting_time)
            # if not qnetwork.sdList:
            #     print(f"第{i+1}次实验")
            #     print(f"{num_timeslot}个时隙后, 所有sd对都建成端到端连接")
            #     print()
            #     # break
            # else:
            #     print(f"第{i+1}次实验：")
            #     # print(f"{num_timeslot}个时隙后, 还剩{qnetwork.sdList}共{len(qnetwork.sdList)}个sd对没有成功建成ec")
            #     print(f"还剩共{len(qnetwork.sdList)}个sd对没有成功建成ec:{qnetwork.sdList}")
            #     print()

            
        
        # print(f"平均每次实验建成{ec_num_counter/the_num}个ec")
        # print("el_waste after loops:", el_waste )

        if function == 0:
            counter_bestresponse = ec_num_counter/(the_num*max_slot_num)
            print("counter_bestresponse:", counter_bestresponse)

            waiting_bestresponse = waiting_time/(the_num*for_sd_num)
            print("waiting_bestresponse:", waiting_bestresponse)

            waste_bestresponse = el_waste/(the_num)
            print("waste_bestresponse:", waste_bestresponse)

        if function == 1:
            counter_pro = ec_num_counter/(the_num*max_slot_num)
            print("counter_pro:", counter_pro)

            waiting_pro = waiting_time/(the_num*for_sd_num)
            print("waiting_pro:", waiting_pro)

            waste_pro = el_waste/(the_num)
            print("waste_pro:", waste_pro)

        if function == 2:
            counter_step = ec_num_counter/(the_num*max_slot_num)
            print("counter_step:", counter_step)

            waiting_step = waiting_time/(the_num*for_sd_num)
            print("waiting_step:", waiting_step)

            waste_step = el_waste/(the_num)
            print("waste_step:", waste_step)

        if function == 3:
            counter_remaining = ec_num_counter/(the_num*max_slot_num)    
            print("counter_remaining:", counter_remaining)

            waiting_remaining = waiting_time/(the_num*for_sd_num)
            print("waiting_remaining:", waiting_remaining)

            waste_remaining = el_waste/(the_num)
            print("waste_remaining:", waste_remaining)



    # index = counter_bestresponse - counter_step


    # print(f"br算法比step算法多建立{index}个ec")   

    # return index
    return counter_bestresponse, counter_pro, counter_step, counter_remaining, \
        waiting_bestresponse, waiting_pro, waiting_step, waiting_remaining,\
    waste_bestresponse, waste_pro, waste_step, waste_remaining 


br = []
pro_f = []
step = []
remaining = []

br_waiting_time = []
pro_f_waiting_time = []
step_waiting_time = []
remaining_waiting_time = []

br_waste = []
pro_f_waste = []
step_waste = []
remaining_waste = []

def write_for_scale():
    node_num_index = []
    node_num_changing = 45
    for i in range(1):
        loop_start_time = time.time()

        print(f"第{i+1}次生成拓扑")
        print(f"节点数量：{node_num_changing}")
        GenerateNetwork("./data/generate_data/generate_for_scale.txt", node_num_changing, sd_num, .55, β, 1, pro)

        counter_bestresponse, counter_pro, counter_step, counter_remaining,\
            waiting_bestresponse, waiting_pro, waiting_step, waiting_remaining,\
            waste_bestresponse, waste_pro, waste_step, waste_remaining = worker("./data/generate_data/generate_for_scale.txt", remaining_num, node_num_changing)

        node_num_index.append(node_num_changing)

        br.append(counter_bestresponse)
        pro_f.append(counter_pro)
        step.append(counter_step)
        remaining.append(counter_remaining)

        br_waiting_time.append(waiting_bestresponse)
        pro_f_waiting_time.append(waiting_pro)
        step_waiting_time.append(waiting_step)
        remaining_waiting_time.append(waiting_remaining)

        br_waste.append(waste_bestresponse)
        pro_f_waste.append(waste_pro)
        step_waste.append(waste_step)
        remaining_waste.append(waste_remaining)

        node_num_changing += 5

        loop_end_time = time.time()
        print(f"本次循环耗时{loop_end_time-loop_start_time} 秒")

    # 将数据写入文件
    with open('./data/experiment_data/throughput_scale.txt', 'w') as f:
        f.write('node_num_index,br,pro_f,step,remaining \n')  # 写入列名
        for i in range(len(node_num_index)):
            f.write(f'{node_num_index[i]},{br[i]},{pro_f[i]},{step[i]},{remaining[i]}\n')  # 写入数据
            
    with open('./data/experiment_data/waiting_scale.txt', 'w') as f:
        f.write('node_num_index,br_waiting_time,pro_f_waiting_time,step_waiting_time,remaining_waiting_time \n')  # 写入列名
        for i in range(len(node_num_index)):
            f.write(f'{node_num_index[i]},{br_waiting_time[i]},{pro_f_waiting_time[i]},{step_waiting_time[i]},{remaining_waiting_time[i]}\n')  # 写入数据        

    with open('./data/experiment_data/waste_scale.txt', 'w') as f:
        f.write('node_num_index,br_waste,pro_f_waste,step_waste,remaining_waste \n')  # 写入列名
        for i in range(len(node_num_index)):
            f.write(f'{node_num_index[i]},{br_waste[i]},{pro_f_waste[i]},{step_waste[i]},{remaining_waste[i]}\n')  # 写入数据        

    print("实验数据已保存到scale相关txt文件中")

def write_for_workload():
    sd_num_index = []
    sd_num_changing = 10
    for i in range(10):
        loop_start_time = time.time()

        print(f"第{i+1}次生成拓扑")
        print(f"sd对数量：{sd_num_changing}")
        GenerateNetwork("./data/generate_data/generate_for_workload.txt", node_num, sd_num_changing, .55, β, 1, pro)

        print("拓扑生成完成")

        counter_bestresponse, counter_pro, counter_step, counter_remaining,\
            waiting_bestresponse, waiting_pro, waiting_step, waiting_remaining,\
            waste_bestresponse, waste_pro, waste_step, waste_remaining = worker("./data/generate_data/generate_for_workload.txt", remaining_num, node_num)

        print("work函数执行中")

        sd_num_index.append(sd_num_changing)

        br.append(counter_bestresponse)
        pro_f.append(counter_pro)
        step.append(counter_step)
        remaining.append(counter_remaining)

        br_waiting_time.append(waiting_bestresponse)
        pro_f_waiting_time.append(waiting_pro)
        step_waiting_time.append(waiting_step)
        remaining_waiting_time.append(waiting_remaining)

        br_waste.append(waste_bestresponse)
        pro_f_waste.append(waste_pro)
        step_waste.append(waste_step)
        remaining_waste.append(waste_remaining)

        sd_num_changing += 5

        loop_end_time = time.time()
        print(f"本次循环耗时{loop_end_time-loop_start_time} 秒")

    # 将数据写入文件
    with open('./data/experiment_data/throughput_workload.txt', 'w') as f:
        f.write('node_num_index,br,pro_f,step,remaining \n')  # 写入列名
        for i in range(len(sd_num_index)):
            f.write(f'{sd_num_index[i]},{br[i]},{pro_f[i]},{step[i]},{remaining[i]}\n')  # 写入数据
            
    with open('./data/experiment_data/waiting_workload.txt', 'w') as f:
        f.write('node_num_index,br_waiting_time,pro_f_waiting_time,step_waiting_time,remaining_waiting_time \n')  # 写入列名
        for i in range(len(sd_num_index)):
            f.write(f'{sd_num_index[i]},{br_waiting_time[i]},{pro_f_waiting_time[i]},{step_waiting_time[i]},{remaining_waiting_time[i]}\n')  # 写入数据        

    with open('./data/experiment_data/waste_workload.txt', 'w') as f:
        f.write('node_num_index,br_waste,pro_f_waste,step_waste,remaining_waste \n')  # 写入列名
        for i in range(len(sd_num_index)):
            f.write(f'{sd_num_index[i]},{br_waste[i]},{pro_f_waste[i]},{step_waste[i]},{remaining_waste[i]}\n')  # 写入数据        

    print("实验数据已保存到workload相关txt文件中")

def write_for_successPro():
    pro_index = []
    pro_changing = 50
    for i in range(10):
        loop_start_time = time.time()

        print(f"第{i+1}次生成拓扑")
        print(f"el平均建成概率:{pro_changing}")
        GenerateNetwork("./data/generate_data/generate_for_successPro.txt", node_num, sd_num, .55, β, 1, pro_changing)

        counter_bestresponse, counter_pro, counter_step, counter_remaining,\
            waiting_bestresponse, waiting_pro, waiting_step, waiting_remaining,\
            waste_bestresponse, waste_pro, waste_step, waste_remaining = worker("./data/generate_data/generate_for_successPro.txt", remaining_num, node_num)

        pro_index.append(pro_changing)

        br.append(counter_bestresponse)
        pro_f.append(counter_pro)
        step.append(counter_step)
        remaining.append(counter_remaining)

        br_waiting_time.append(waiting_bestresponse)
        pro_f_waiting_time.append(waiting_pro)
        step_waiting_time.append(waiting_step)
        remaining_waiting_time.append(waiting_remaining)

        br_waste.append(waste_bestresponse)
        pro_f_waste.append(waste_pro)
        step_waste.append(waste_step)
        remaining_waste.append(waste_remaining)

        pro_changing += 5

        loop_end_time = time.time()
        print(f"本次循环耗时{loop_end_time-loop_start_time} 秒")

    # 将数据写入文件
    with open('./data/experiment_data/throughput_successPro.txt', 'w') as f:
        f.write('sd_num_index,br,pro_f,step,remaining \n')  # 写入列名
        for i in range(len(pro_index)):
            f.write(f'{pro_index[i]},{br[i]},{pro_f[i]},{step[i]},{remaining[i]}\n')  # 写入数据
            
    with open('./data/experiment_data/waiting_successPro.txt', 'w') as f:
        f.write('sd_num_index,br_waiting_time,pro_f_waiting_time,step_waiting_time,remaining_waiting_time \n')  # 写入列名
        for i in range(len(pro_index)):
            f.write(f'{pro_index[i]},{br_waiting_time[i]},{pro_f_waiting_time[i]},{step_waiting_time[i]},{remaining_waiting_time[i]}\n')  # 写入数据        

    with open('./data/experiment_data/waste_successPro.txt', 'w') as f:
        f.write('sd_num_index,br_waste,pro_f_waste,step_waste,remaining_waste \n')  # 写入列名
        for i in range(len(pro_index)):
            f.write(f'{pro_index[i]},{br_waste[i]},{pro_f_waste[i]},{step_waste[i]},{remaining_waste[i]}\n')  # 写入数据        

    print("实验数据已保存到successPro相关txt文件中")

def write_for_connectivity():
    β_index = []
    β_changing = 0.06
    for i in range(10):
        loop_start_time = time.time()

        print(f"第{i+1}次生成拓扑")
        print(f"β值：{β_changing}")
        GenerateNetwork("./data/generate_data/generate_for_connectivity.txt", node_num, sd_num, .55, β_changing, 1, pro)

        counter_bestresponse, counter_pro, counter_step, counter_remaining,\
            waiting_bestresponse, waiting_pro, waiting_step, waiting_remaining,\
            waste_bestresponse, waste_pro, waste_step, waste_remaining = worker("./data/generate_data/generate_for_connectivity.txt", remaining_num, node_num)

        β_index.append(β_changing)

        br.append(counter_bestresponse)
        pro_f.append(counter_pro)
        step.append(counter_step)
        remaining.append(counter_remaining)

        br_waiting_time.append(waiting_bestresponse)
        pro_f_waiting_time.append(waiting_pro)
        step_waiting_time.append(waiting_step)
        remaining_waiting_time.append(waiting_remaining)

        br_waste.append(waste_bestresponse)
        pro_f_waste.append(waste_pro)
        step_waste.append(waste_step)
        remaining_waste.append(waste_remaining)

        β_changing += 0.01

        loop_end_time = time.time()
        print(f"本次循环耗时{loop_end_time-loop_start_time} 秒")

    # 将数据写入文件
    with open('./data/experiment_data/throughput_connectivity.txt', 'w') as f:
        f.write('β_index,br,pro_f,step,remaining \n')  # 写入列名
        for i in range(len(β_index)):
            f.write(f'{β_index[i]},{br[i]},{pro_f[i]},{step[i]},{remaining[i]}\n')  # 写入数据
            
    with open('./data/experiment_data/waiting_connectivity.txt', 'w') as f:
        f.write('β_index,br_waiting_time,pro_f_waiting_time,step_waiting_time,remaining_waiting_time \n')  # 写入列名
        for i in range(len(β_index)):
            f.write(f'{β_index[i]},{br_waiting_time[i]},{pro_f_waiting_time[i]},{step_waiting_time[i]},{remaining_waiting_time[i]}\n')  # 写入数据        

    with open('./data/experiment_data/waste_connectivity.txt', 'w') as f:
        f.write('β_index,br_waste,pro_f_waste,step_waste,remaining_waste \n')  # 写入列名
        for i in range(len(β_index)):
            f.write(f'{β_index[i]},{br_waste[i]},{pro_f_waste[i]},{step_waste[i]},{remaining_waste[i]}\n')  # 写入数据        

    print("实验数据已保存到connectivity相关txt文件中")

def write_for_el_remain():
    remaining_num_index = []
    remaining_num_changing = 2
    for i in range(8):
        loop_start_time = time.time()

        print(f"第{i+1}次生成拓扑")
        print(f"el可持续时隙数:{remaining_num_changing}")
        GenerateNetwork("./data/generate_data/generate_for_el_remain.txt", node_num, sd_num, .55, β, 1, pro)

        counter_bestresponse, counter_pro, counter_step, counter_remaining,\
            waiting_bestresponse, waiting_pro, waiting_step, waiting_remaining,\
            waste_bestresponse, waste_pro, waste_step, waste_remaining = worker("./data/generate_data/generate_for_el_remain.txt", remaining_num_changing, node_num)

        remaining_num_index.append(remaining_num_changing)

        br.append(counter_bestresponse)
        pro_f.append(counter_pro)
        step.append(counter_step)
        remaining.append(counter_remaining)

        br_waiting_time.append(waiting_bestresponse)
        pro_f_waiting_time.append(waiting_pro)
        step_waiting_time.append(waiting_step)
        remaining_waiting_time.append(waiting_remaining)

        br_waste.append(waste_bestresponse)
        pro_f_waste.append(waste_pro)
        step_waste.append(waste_step)
        remaining_waste.append(waste_remaining)

        remaining_num_changing += 1

        loop_end_time = time.time()
        print(f"本次循环耗时{loop_end_time-loop_start_time} 秒")

    # 将数据写入文件
    with open('./data/experiment_data/throughput_el_remaining.txt', 'w') as f:
        f.write('remaining_num_index,br,pro_f,step,remaining \n')  # 写入列名
        for i in range(len(remaining_num_index)):
            f.write(f'{remaining_num_index[i]},{br[i]},{pro_f[i]},{step[i]},{remaining[i]}\n')  # 写入数据
            
    with open('./data/experiment_data/waiting_el_remaining.txt', 'w') as f:
        f.write('remaining_num_index,br_waiting_time,pro_f_waiting_time,step_waiting_time,remaining_waiting_time \n')  # 写入列名
        for i in range(len(remaining_num_index)):
            f.write(f'{remaining_num_index[i]},{br_waiting_time[i]},{pro_f_waiting_time[i]},{step_waiting_time[i]},{remaining_waiting_time[i]}\n')  # 写入数据        

    with open('./data/experiment_data/waste_el_remaining.txt', 'w') as f:
        f.write('remaining_num_index,br_waste,pro_f_waste,step_waste,remaining_waste \n')  # 写入列名
        for i in range(len(remaining_num_index)):
            f.write(f'{remaining_num_index[i]},{br_waste[i]},{pro_f_waste[i]},{step_waste[i]},{remaining_waste[i]}\n')  # 写入数据        

    print("实验数据已保存到el_remaining相关txt文件中")

# index_counter = 0
# for i in range(loop_num):
#     print()
#     # print(f"第{i+1}次测试") 
    
#     index = worker()
#     index_counter += index

# print(f"the average of index is {index_counter/loop_num}")


# end_time = time.time()

# total_time = end_time - start_time

# print(f"程序执行总时间为: {total_time} 秒")

# print("默认各项参数：")
# print(f"node数量： {node_num}， sd对数量:{sd_num}， el创建成功率:{pro}， el可持续时隙数：{remaining_num}， 贝塔值：{β}")
# print("各项参数：")
# print(f"时隙数：{max_slot_num}，单轮实验次数：{the_num}，轮数：{loop_num}，el可持续时隙数：{remaining_num}")







